package com.zhijs.struts.action;

import static java.lang.System.out;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import org.apache.commons.collections.map.MultiValueMap;
import org.apache.commons.dbutils.DbUtils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.MapHandler;
import org.apache.commons.dbutils.handlers.MapListHandler;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.apache.struts2.interceptor.SessionAware;

import com.h819.core.db.MyDbUtils;
import com.h819.core.web.jqgrid.JqgridListBaseAction;
import com.h819.core.web.jqgrid.Page;

/**
 * @ClassName: ShowUpdatesAction
 * @Description: TODO(临时显示更新用)
 * @author h819
 * @date 2009-11-30 下午02:40:38
 * @version V1.0
 */

// 本方法进行了三次查询，效率不高
// 原因，深圳的代替标准不规范，无法用 sql 统一处理，只能用编程序的方法处理
// 以后看看 sql 能否解决

// 研究 runner 的返回值。如果没有查询结果，返回值是 null
public class ShowStdUpdateListAction extends JqgridListBaseAction implements
		SessionAware {

	Logger log = Logger.getLogger(ShowStdUpdateListAction.class);

	Map session;

	private QueryRunner runner = new QueryRunner();;
	private Connection conn = null;

	Page p = this.getPage();

	int totalRecords;

	// 每页记录数
	// int pageSize = conf.getInt("pagesize");// 每页显示记录数，默认为10条;
	// 默认当前页
	int defaultPage = 1;
	// 当前页数
	int page = 0;

	public String execute() throws Exception {

		if (conn == null)
			log.info("conn is null ");
		else
			log.info("conn is close");

		log.info("isSearch() : " + isSearch());
		if (this.isSearch()) {
			search();
			return SUCCESS;
		}
		// 准备数据
		prepareDate();

		// 以下变量，必须赋值
		this.setCurPageNo(p.getPageNo());
		this.setTotalPages(p.getTotalPages());
		this.setTotalRecords(p.getTotalCount());
		this.setDataRows(this.getDataRows());

		log.info("当前页号：" + p.getPageNo());
		log.info("每页显示数据数量：" + p.getPageSize());
		log.info("数据总量：" + p.getTotalCount());
		log.info("排序变量：" + p.getOrderBy());
		log.info("升序/降序：" + p.getOrder());

		log.info("getDataRows size:" + this.getDataRows().size());

		for (Map m : this.getDataRows()) {
			StringUtils.center("getDataRows list ", 80, '*');
			for (Iterator it = m.entrySet().iterator(); it.hasNext();) {
				Map.Entry entry = (Map.Entry) it.next();
				// System.out.println(entry.getKey() + " = "
				// + entry.getValue());
			}
		}

		return SUCCESS;
	}

	private void prepareDate() {

		conn = MyDbUtils.getInstance("h819.properties").getOracleConnection235();

		try {
			// 计算记录数目
			String queryCount = "select count(1) "
					+ "from zhijs_standard  a, st_standard  b where "
					+ "a.st_standardcode = b.standard_code and "
					+ "b.replace_standard is not null ";

			log.info("queryCount : " + queryCount);

			// 计算记录总数
			Map<String, Object> r7 = runner.query(conn, queryCount,
					new MapHandler());
			for (Iterator it = r7.entrySet().iterator(); it.hasNext();) {
				Map.Entry entry = (Map.Entry) it.next();
				totalRecords = Integer.parseInt(entry.getValue().toString());
				entry.getValue();
				// out.println(entry.getKey() + " = " + entry.getValue());
			}

			// 放入 session ，用于显示更新总数
			session.put("totalRecords_update", totalRecords);

			// 给 page 设置必要参数
			p.setTotalCount(totalRecords);

			// 计算分页
			int begin = p.getFirst();
			int end = begin + p.getPageSize() - 1;
			if (end >= this.getTotalRecords())
				end = Long.valueOf(this.getTotalRecords()).intValue();
			
			// 起始位置
			String limitFrom = String.valueOf(begin);
			// 结束位置
			String limitTo = String.valueOf(end);

			log.info("in zhijs : limitFrom = " + limitFrom);
			log.info("in zhijs : limitTo = " + limitTo);

			// 查询所有的有更新的标准
			String queryList = "select temptable.*  from( "
					+ "select  row_number() over(order by zjs.zhijs_departmentcode) as num, "
					+ "zjs.* " + "from zhijs_view zjs "
					+ "where zjs.zhijs_replace_standard is not null  )"
					+ "temptable where  num between " + limitFrom + " AND "
					+ limitTo+"  order by zhijs_typename";;

			log.info("queryList = " + queryList);

			List<Map<String, Object>> newSearchDataTemp;
			List<Map<String, Object>> stModifyTemp;

			newSearchDataTemp = runner.query(conn, queryList,
					new MapListHandler());

			// 重新构造返回值，每次都重新初始化
			List<Map<String, Object>> newSearchData = new ArrayList<Map<String, Object>>();

			// 用于存放关系查询新标准：标准号、文本地址和实施日期
			Map<String, Object> runnerResultTemp;

			// 用于存放文本信息
			ArrayList<MultiValueMap> textAddressList = new ArrayList<MultiValueMap>();
			
			// 记录序号，和 NUM 不同，此 id 用来记录记录集的排序号，可以区分选择了哪条记录.下载文件的时候用的此变量
			int id = 0;
			if (newSearchDataTemp != null)
				for (Map m : newSearchDataTemp) {// 查询所有的有更新的标准,每次循环是一条标准题录
					out.println(StringUtils.center("标准更新题录信息", 80, '*'));
					id++;

					// 临时变量，重新组合数据用重新构造返回值
					Map<String, Object> tempMap = new TreeMap<String, Object>();
					// 存放找到的文本地址信息,和 ArrayList<Map<String, String>> textAddress
					// 配合使用
					// 设计成可以存放多值value的MultiValueMap，这样一个标准号，可以对应多个 修改单地址了
					MultiValueMap tempMultiMap = new MultiValueMap();

					// TreeMap<String, Object> temptm = new TreeMap<String,
					// Object>();

					for (Iterator it = m.entrySet().iterator(); it.hasNext();) { // 每条标准的具体信息
						Map.Entry entry = (Map.Entry) it.next();
						 System.out.println(entry.getKey() + " = "
						 + entry.getValue());

						// 逐个查询新标准的文本地址。是根据托管标准（旧标准）的代替标准来查找新标准信息的。
						// 而代替标准的格式不规范，需要用程序来规范，所以不在 sql 中处理.


						// 查询新标准
						if (entry.getKey().toString().equals(
								"ZHIJS_REPLACE_STANDARD")) {// StandardCodeUtils

							String newStandard = "select st.standard_code as zhijs_new_standardcode,st.namecn as zhijs_new_standardnamecn,st.text_address as zhijs_new_text_address,st.act_time as zhijs_new_act_time from st_standard st where st.standard_code ='"
									+ getReplacedStandardCodeFromShenZhen(entry
													.getValue().toString()) + "'";
							// 新标准信息,只会有一条，故用 MapHandler()
							log.info("newStandard : " + newStandard);
							runnerResultTemp = runner.query(conn, newStandard,
									new MapHandler());

							out.println(StringUtils.center("平台库新标准查询", 40, '*'));
							if (runnerResultTemp != null)// runner
								// 的返回值是null，需要判断
								for (Iterator it9 = runnerResultTemp.entrySet()
										.iterator(); it9.hasNext();) {
									Map.Entry entry9 = (Map.Entry) it9.next();
									
									out.println(entry9.getKey() + " = "
											+ entry9.getValue());
									
									
									if (entry9.getKey().toString().equals(
											"ZHIJS_NEW_ACT_TIME")) { // 重新设置日期，这里可能设定格式化，以后再研究
										if (entry9.getValue() != null)
											tempMap.put(entry9.getKey()
													.toString(), StringUtils
													.substringBefore(entry9
															.getValue()
															.toString(),
															"T00:00:00"));
									} else if (entry9.getKey().toString()
											.equals("ZHIJS_NEW_TEXT_ADDRESS")) {// 保存文本地址

										// 由于都转换为了 String 类型，需要判断空值
										String value = "";
										if (entry9.getValue() != null)
											value = entry9.getValue()
													.toString();

										tempMultiMap.put(entry9.getKey()
												.toString(), value);

										tempMap.put(entry9.getKey().toString(),
												"浏览");

									} else if (entry9.getKey().toString()
											.equals("ZHIJS_NEW_STANDARDCODE")) {

										// 由于都转换为了 String 类型，需要判断空值
										String value = "";
										if (entry9.getValue() != null)
											value = entry9.getValue()
													.toString();

										// 保留最新的标准号
										tempMultiMap.put(entry9.getKey()
												.toString(), value);

										tempMap.put(entry9.getKey().toString(),
												entry9.getValue());

									} else if (entry9.getKey().toString()
											.equals("ZHIJS_NEW_STANDARDNAMECN")) { // 新标准名称

										// 由于都转换为了 String
										// 类型，需要判断空值ZHIJS_NEW_STANDARDNAMECN
										String value = "";
										if (entry9.getValue() != null)
											value = entry9.getValue()
													.toString();

										tempMap.put(entry9.getKey().toString(),
												value);

									} else
										tempMap.put(entry9.getKey().toString(),
												entry9.getValue());

									// r8.add(r9);
								}// 查询新标准详细信息

						}// 提取新标准号完成

						// 查询旧的托管标准是否有修改单，并且查出标准名称
						else if (entry.getKey().toString().equals(
								"ZHIJS_STTANDARDCODE")) {// StandardCodeUtils
							String stModify = "select  stmod.modify_id,stmod.standard_code,std.namecn,stmod.modify_number,stmod.file_address from st_modify stmod,st_standard std where stmod.standard_code=std.standard_code and stmod.standard_code ='"
									+ entry.getValue().toString() + "'";

							log.info("stModify : " + stModify);
							stModifyTemp = runner.query(conn, stModify,
									new MapListHandler());
							if (stModifyTemp != null)// runner 的返回值是null，需要判断
								for (Map mm : stModifyTemp) {
									for (Iterator itstMod = mm.entrySet()
											.iterator(); itstMod.hasNext();) {
										Map.Entry entrystMod = (Map.Entry) itstMod
												.next();
										out.println(StringUtils.center("修改单查询", 40, '*'));
										out.println(entrystMod.getKey() + " = "
												+ entrystMod.getValue());

										if (entrystMod.getKey().toString()
												.equals("FILE_ADDRESS")) {// 保存修改单地址信息

											// 由于都转换为了 String 类型，需要判断空值
											String value = "";
											if (entrystMod.getValue() != null)
												value = entrystMod.getValue()
														.toString();

											tempMultiMap
													.put(entrystMod.getKey()
															.toString(), value);
										}

										if (entrystMod.getKey().toString()
												.equals("NAMECN")) {// 保存标准名称

											// 由于都转换为了 String 类型，需要判断空值
											String value = "";
											if (entrystMod.getValue() != null)
												value = entrystMod.getValue()
														.toString();

											tempMap.put(entrystMod.getKey()
													.toString(), value);
										}

									}

								}// 提取修改单

							if (stModifyTemp != null
									&& stModifyTemp.size() != 0)
								tempMap.put("stModifySum", stModifyTemp.size()
										+ ",  查看");

							// ZHIJS_STTANDARDCODE 也放入 map
							tempMap.put(entry.getKey().toString(), entry
									.getValue());

							// 旧的托管标准放入带查询的结构
							String value = "";
							if (entry.getValue() != null)
								value = entry.getValue().toString();
							tempMultiMap.put(entry.getKey().toString(), value);

						}// 查询修改单详细信息完毕。

						else if (entry.getKey().toString().equals(
								"ZHIJS_TEXT_ADDRESS")) {// 保存旧标准的地址信息

							// 由于都转换为了 String 类型，需要判断空值
							String value = "";
							if (entry.getValue() != null)
								value = entry.getValue().toString();

							tempMultiMap.put(entry.getKey().toString(), value);

							tempMap.put(entry.getKey().toString(), "浏览");

						}

						else if (entry.getKey().toString().equals("NUM")) {// 保存旧标准的地址信息

							// 由于都转换为了 String 类型，需要判断空值
							String value = "";
							if (entry.getValue() != null)
								value = entry.getValue().toString();

							tempMultiMap.put(entry.getKey().toString(), value);

							tempMap.put(entry.getKey().toString(), entry
									.getValue());

						}
						else if (entry.getKey().toString().equals("ZHIJS_DEPARTMENTCODE")) {// 保存托管标准的部门信息，更新操作时，用到

							// 由于都转换为了 String 类型，需要判断空值
							String value = "";
							if (entry.getValue() != null)
								value = entry.getValue().toString();

							tempMultiMap.put(entry.getKey().toString(), value);

							tempMap.put(entry.getKey().toString(), entry
									.getValue());

						}
						
						
						
						else {
							// 其他字段不做处理
							tempMap.put(entry.getKey().toString(), entry
									.getValue());				
						}
						
						tempMap.put("ACTION", "更新");

					}// 查询单条托管标准详细信息完成

					// 记录行号，便于以后定位该条记录
					tempMultiMap.put("id", Integer.valueOf(id).toString());
					newSearchData.add(tempMap);
					textAddressList.add(tempMultiMap);

				}// 逐条查询托管标准完成

			//为页面赋值
			this.setDataRows(newSearchData);

			// 放入 session ，下载文件时,再次检索
			session.put("resultdata", textAddressList);

		} catch (SQLException e) {
			DbUtils.printStackTrace(e);

		} finally {
			DbUtils.closeQuietly(conn);
		}
	}

	public void search() {

		Page p = this.getPage();

		// 准备数据
		// 清空原来的数据
		// this.getDataRows().clear();
		// prepareDate(this.searchSize);
		// 第一次查询时，显示为第一页。此时 传过来的参数 page 值为 0

		// 测试是否已经根据 prmNames 参数设置自动赋值
		log.info("当前页号：" + p.getPageNo());
		log.info("每页显示数据数量：" + p.getPageSize());
		log.info("排序变量：" + p.getOrderBy());
		log.info("升序/降序：" + p.getOrder());

		// 给 page 设置必要参数
		p.setTotalCount(this.getDataRows().size());
		// page 类根据每页记录数量和总记录数计算出
		log.info("总页数：" + p.getTotalPages());

		log.info("isSearch :" + this.isSearch());
		log.info("Search :" + this.getSearch());
		log.info("SearchField :" + this.getSearchField());
		log.info("SearchString :" + this.getSearchString());
		log.info("SearchOper :" + this.getSearchOper());

		// 以下变量，必须赋值
		this.setCurPageNo(p.getPageNo());
		this.setTotalPages(p.getTotalPages());
		this.setTotalRecords(p.getTotalCount());
		this.setDataRows(this.getDataRows());
	}

	
	/**
	 * 用来规范深圳的不规范的代替代替标准号
	 * 
	 * @param shenZhenreplacedStandardCode
	 *            深圳不规范的标准号
	 * @return
	 */
	private String getReplacedStandardCodeFromShenZhen(
			String shenZhenreplacedStandardCode) {

		// 只规范下面几种情形：
		// GB/T 8967-2007;
		// SS GB/T 8967-2007

		shenZhenreplacedStandardCode = StringUtils.remove(
				shenZhenreplacedStandardCode, ";");
		int i = StringUtils.countMatches(shenZhenreplacedStandardCode, " ");
		if (i == 1)// 合法
			return shenZhenreplacedStandardCode;
		if (i > 1)// 取第一个空格后面的字符串
			return StringUtils
					.substringAfter(shenZhenreplacedStandardCode, " ");
		return "";

	}
	
	/*
	 * 以下getter方法必须实现，struts2-json插件会将这些getter方法序列化，以便输出json对象。
	 * 这些getter方法只需返回相应的属性即可。如getCurPage应该返回curPage （curPage在JsonBaseAction中有定义）
	 */
	@Override
	public int getCurPageNo() {
		return this.curPageNo;
	}

	@Override
	public List<Map<String, Object>> getDataRows() {
		return this.dataRows;
	}

	@Override
	public long getTotalPages() {
		return this.totalPages;
	}

	@Override
	public long getTotalRecords() {
		return this.totalRecords;
	}

	public static void main(String[] args) {

		ShowStdUpdateListAction sa = new ShowStdUpdateListAction();
		try {
			sa.execute();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	public void setSession(Map session) {
		this.session = session;
	}
}
